package ru.urfc.portal.dao.impl;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.annotation.Resource;
import javax.ejb.Stateless;
import javax.sql.DataSource;

import ru.urfc.portal.dao.AttachedFileDao;
import ru.urfc.portal.exceptions.InternalException;
import ru.urfc.portal.model.documents.AttachedFile;
import ru.urfc.portal.ui.client.Constants;

@Stateless
public class AttachedFileDaoImpl extends BaseDao implements AttachedFileDao {
	
	@Resource(name = Constants.JNDI_DATA_SOURCE_SYS)
	DataSource dataSource;
	
	static public class WriteAttachedFileContentException extends InternalException {
		public WriteAttachedFileContentException(Throwable cause, String messageTemplate, Object... arguments) {
			super(cause, messageTemplate, arguments);
		}
	}
	
	static public class ReadAttachedFileContentException extends InternalException {
		public ReadAttachedFileContentException(Throwable cause, String messageTemplate, Object... arguments) {
			super(cause, messageTemplate, arguments);
		}
	}
	
	@Override
	public void writeContent(AttachedFile attachedFile, InputStream content, int length) {
		getSysEntityManager().flush();
		try {
			Connection connection = dataSource.getConnection();
			PreparedStatement statement = connection.prepareStatement(format(
					"UPDATE {0} SET content = ? WHERE id = ?", AttachedFile.class.getSimpleName()));
			statement.setBinaryStream(1, content, length);
			statement.setLong(2, attachedFile.getId());
			statement.executeUpdate();
		} catch (SQLException e) {
			throw new WriteAttachedFileContentException(e, "Unable write content to file ''{0}''", attachedFile.getName());
		}
	}

	@Override
	public InputStream readContent(AttachedFile attachedFile) {
		getSysEntityManager().flush();
		try {
			Connection connection = dataSource.getConnection();
			PreparedStatement statement = connection.prepareStatement(format(
					"SELECT this.content FROM {0} this WHERE this.id = ?", AttachedFile.class.getSimpleName()));
			statement.setLong(1, attachedFile.getId());
			statement.execute();
			ResultSet resultSet = statement.getResultSet();
			resultSet.next();
			return resultSet.getBinaryStream("content");
		} catch (SQLException e) {
			throw new ReadAttachedFileContentException(e, "Unable read file content ''{0}''", attachedFile.getName());
		}
	}
	
}
